﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace CircleBarDemo
{
    class RingProgramBar : Control
    {
        //这个写最上面是因为我自己也不懂是啥意思，只知道界面控件高速的重绘容易产生闪烁的问题，这个加了就不会有
        protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000; return cp; } }

        //-------------------颜色
        private Color bgColor = Color.FromArgb(224, 224, 224);   //背景边框颜色
        private Color sectorColor = Color.FromArgb(109, 179, 63);   //扇形颜色
        [Description("进度条背景颜色")]
        public Color BgColor
        {
            get { return this.bgColor; }
            set
            {
                this.bgColor = value;
                this.Invalidate();
            }
        }
        [Description("进度条颜色")]
        public Color SectorColor
        {
            get { return this.sectorColor; }
            set
            {
                this.sectorColor = value;
                this.Invalidate();
            }
        }

        private int borderWidth = 2;        //边框宽度
        [Description("进度条的宽度")]
        public int BorderWidth
        {
            get { return this.borderWidth; }
            set
            {
                this.borderWidth = value;
                this.Invalidate();
            }
        }
        private float startAngle = 270;        
        [Description("进度条开始的角度")]
        public float StartAngle
        {
            get { return this.startAngle; }
            set
            {
                this.startAngle = value;
                this.Invalidate();
            }
        }
        /// <summary>
        /// 圆形进度条实心
        /// </summary>
        public RingProgramBar()
        {
            InitControl();
            this.SizeChanged += delegate
            {
                this.Invalidate(); //重绘控件
            };
        }

        int maxValue = 100;   //进度最大值
        private int progress = 0;
        [Description("进度值")]
        public int Progress
        {
            get { return this.progress; }
            set
            {
                if (value > this.maxValue)
                {
                    return;
                }
                this.progress = value;
                this.Invalidate();
            }
        }

        /// <summary>
        /// 初始化控件参数
        /// </summary>
        private void InitControl()
        {
            this.Width = 200;
            this.Height = 200;
        }

        //对Control进行绘制
        protected override void OnPaint(PaintEventArgs e)
        {
            DrawShape(e.Graphics);    //绘制控件样式
        }
        Point[] CalculateArcPoints(Point center,double radius, double endAngle)
        {
            double startAngleInRadians = Math.PI * 0 / 180;
            double sx = radius * Math.Cos(startAngleInRadians);
            double sy = radius * Math.Sin(startAngleInRadians);
            Point startpoint = new Point((int)(center.X - sy - borderWidth / 2), (int)(center.Y - sx));

            double endAngleInRadians = Math.PI * endAngle / 180;
            double dx = radius * Math.Cos(endAngleInRadians);
            double dy = radius * Math.Sin(endAngleInRadians);

            Point endpoint;

            if (endAngle <= 90)
             endpoint = new Point((int)(center.X + dy - borderWidth), (int)(center.Y - dx - borderWidth / 2));
            else if (endAngle <= 180)
                endpoint = new Point((int)(center.X + dy - borderWidth/2), (int)(center.Y - dx - borderWidth));
            else if (endAngle <= 270)
                endpoint = new Point((int)(center.X + dy), (int)(center.Y + dx));
            else
                endpoint = new Point((int)(center.X + dy), (int)(center.Y + dx));

            return new Point[] { startpoint, endpoint };

        }
        /// <summary>
        /// 画图
        /// </summary>
        /// <param name="g">画图工具类</param>
        private void DrawShape(Graphics g)
        {
            Rectangle m_rect;
            if (this.Width < borderWidth * 4 || this.Height < borderWidth * 4)
            {
                return;
            }
            g.SmoothingMode = SmoothingMode.AntiAlias;          //消除锯齿，也就是抗锯齿什么鬼东西
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.CompositingQuality = CompositingQuality.HighQuality;

            RectangleF bg_rectangle = new RectangleF(0 + borderWidth, 0 + borderWidth, Width - borderWidth * 2, Height - borderWidth * 2);    //控件整体坐标

            g.DrawEllipse(new Pen(bgColor, borderWidth), bg_rectangle);  //画背景圆

            Rectangle rl = new Rectangle(0 + borderWidth, 0 + borderWidth, this.Width - borderWidth * 2, this.Height - borderWidth * 2);

            decimal topAngle = (this.progress * 1.0M / this.maxValue) * 360M;//计算进度条划过的度数
            g.DrawArc(new Pen(sectorColor, borderWidth), rl, startAngle, (float)topAngle);   //填充环形
   
            SizeF fs = g.MeasureString(this.progress.ToString() + "%", this.Font);//计算文字的范围

            g.DrawString(this.progress.ToString() + "%", this.Font, new SolidBrush(this.ForeColor),
                bg_rectangle.X + bg_rectangle.Width / 2 - fs.Width / 2, bg_rectangle.Y + bg_rectangle.Height / 2 - fs.Height / 2);
        }


    }
}
